﻿using System;
using System.Runtime.InteropServices;

using SharpDX;
using SharpDX.XAPO;
using SynergyLib.DSP;
using SynergyLib.SMath;

namespace XAudio2Controls
{
    [StructLayout(LayoutKind.Sequential)]
    public struct DelayVibratoParams
    {        
        internal float DelayMS { get; set; }
        internal float ModFreq { get; set; }
    }

    public class DelayVibratoEffect : AudioProcessorBase<DelayVibratoParams>
    {
         public DelayVibratoEffect()
        {
            RegistrationProperties = new RegistrationProperties()
            {
                Clsid = Utilities.GetGuidFromType(typeof(DelayVibratoEffect)),
                CopyrightInfo = "Copyright",
                FriendlyName = "DelayVibrato",
                MaxInputBufferCount = 100,
                MaxOutputBufferCount = 100,
                MinInputBufferCount = 100,
                MinOutputBufferCount = 100,
                Flags = PropertyFlags.Default
            };           
        }

         public override void Process(BufferParameters[] inputProcessParameters, BufferParameters[] outputProcessParameters, bool isEnabled)
         {
             int frameCount = inputProcessParameters[0].ValidFrameCount;
             DataStream input = new DataStream(inputProcessParameters[0].Buffer, frameCount * InputFormatLocked.BlockAlign, true, true);
             DataStream Output = new DataStream(inputProcessParameters[0].Buffer, frameCount * InputFormatLocked.BlockAlign, true, true);
             for (int i = 0; i < frameCount; i++, Counter++ )
             {
                 float left = input.Read<float>();                 
                 float right = input.Read<float>();
                 //Output.Write(left * (float)Delay(left));
                 //Output.Write(right * (float)Delay(right));
                 Output.Write(left * (float)DelayBasedEffects.Delay(left, Parameters.DelayMS, Counter, Parameters.ModFreq, InputFormatLocked.SampleRate));
                 Output.Write(right * (float)DelayBasedEffects.Delay(right, Parameters.DelayMS, Counter, Parameters.ModFreq, InputFormatLocked.SampleRate));
             }
         }
         private double Delay(float input)
         {
             return (input + (1 - Parameters.DelayMS) * (Math.Sin(Trig.TwoPI * Counter * Parameters.ModFreq / InputFormatLocked.SampleRate)));         
         }
       }       
    }

